/**
 * 根据指定的卡片模型保存数据
 *
 *
 * 输入参数:
 *   Card:       必需,     字符串,        卡片名称
 *   Model:      可选,     数组,          字段模型. 字段名称的数组. 如果值为空, 将更新Records中的每个字段. 否则将只更新Model指定的字段
 *   Record:     可选,     键值对象,       要保存的数据. 键要对应到Model中的别名
 *   Records:    可选,     键值对象数组,   要保存的数据. 键要对应到Model中的别名
 * 
 * 输出:
 *   [{record, create_mode}]: 保持结果的数组
 */
(function () {
  function CardW({ UID, Card, Model = null, Record, Records }) {
    // 验证用户
    if (!UID) throw Error("未授权的访问");

    Records ??= [Record];

    // Records必须是数组类型
    if (Records && !Array.isArray(Records)) throw Error('Records要求是数组类型');

    var v_card = A.card[Card];

    if (Model == null) {
      // 更新提供的所有值, 包括引用级联
      return Records.map(record => v_card.save(record, UID))
    } else {
      // 指定Model后, 仅更新Model的值. 不会处理引用级联
      return Records.map(record => {
        const values = { ID: record.ID };
        Model.forEach(m => {
          values[m] = record[m] && Object.getPrototypeOf(record[m]) === Object.prototype ? record[m].ID : record[m];
        });
        return v_card.save(values, UID);
      });
    }
  }

  return (arg1, arg2, arg3, arg4) => {
    if (typeof arg1 === 'string' && typeof arg2 === 'string') {
      let records = [];
      if (Array.isArray(arg4)) {
        records = arg4;
      } else {
        records.push(arg4);
      }
      return CardW({
        UID: arg1,
        Card: arg2,
        Model: arg3,
        Records: records,
      });
    } else {
      // 检查卡片访问控制表
      if (arg2 && A.setting('EnableCardACL')) {
        const acl = A.cache.get(`CardACL.${arg1.Card}`, () => {
          return A.db.execute('KERNEL', "SELECT * FROM KPFWKZ WHERE KPMC=?", [arg1.Card]).rows;
        }, 60); // 缓存60秒
        if (!acl.some(item => !!item.KFKX) && !A.job.JobEvent({
          Event: 'OnCheckPageACL',
          UID: arg1.UID,
          PageIds: acl.filter(item => item.GLYM_ID).map(item => item.GLYM_ID),
        }, arg2)) {
          throw Error("You are not authorized to access this card");
        }
      }
      return CardW(arg1);
    }
  };
})()